package GenericBox2;

public class BoxDriver {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		OldBox box = new OldBox(42);
	    
	    // Show that what you put in is what you get out.
	    System.out.println("Box(42).getData() = " + box.getData());
		
	    // The following line should not compile -- "incompatible type" error.
	    //intBox = new Box<String>("Hello");
	    
	    // The following line gives a "cannot find symbol" error when 
	    // compiled because the constructor call doesn't match its defined signature.
	    //intBox = new Box<Integer>("Hello");
	    
	    // Verify the type of the returned object.
	    System.out.println("OldBox.getData()type =" + box.getData().getClass().toString());
	       
	
	    // no problem with assigning to the same type
	    int x = (Integer) box.getData();
	    
	    // compiler allows an illegal assignment to a different type
	    try {
	      String s = (String) box.getData();
	      System.out.println("Should not allow casting of an Integer to a String");
	    }
	    catch(ClassCastException e) {
	      // This is the proper exception here.
	    }
	    catch(Exception e) {
	      System.out.println("Wrong exception: "+ e);
	    }
	    
	    box = new OldBox("Howdy");
	    
	    // Show that what you put in is what you get out.
	    System.out.println("Box(Howdy).getData() = " + box.getData());
	    
	    // Verify the type of the returned object.
	    System.out.println("OldBox.getData()type =" + box.getData().getClass().toString());
	    
	  
	    Box<?> intBox = new Box<Integer>(42);
	    
	    // Show that what you put in is what you get out.
	   System.out.println("Box(42).getData() =" + intBox.getData());
	    
	    
	   //Type mismatch
	   //int x = intBox.getData();    
	    
	    // Verify the type of the returned object.
	    System.out.println("Box<Integer>.getData()type = " + intBox.getData().getClass().toString());
	    
	    Box<?> strBox = new Box<String>("Howdy");
	    
	    // The following line should not compile -- "incompatible type" error.
	    intBox = new Box<String>("Hello");
	    
	    // The following line gives a "cannot find symbol" error when 
	    // compiled because the constructor call doesn't match its defined signature.
	    //intBox = new Box<Integer>("Hello");
	    
	    String s = (String) intBox.getData();
	  /*  
	    // Show that what you put in is what you get out.
	    assertEquals("Box(Howdy).getData()", "Howdy", strBox.getData());
	    // Verify the type of the returned object.
	    assertEquals("Box<String>.getData()type", "class java.lang.String", strBox.getData().getClass().toString());
	    
	    // Evidence of type erasure by the compiler.
	    // The JRE thinks that Box<String> and Box<Integer> are the same class.
	    assertEquals("Box<String> = Box<Integer> class", strBox.getClass(), intBox.getClass());
	    
	    // The following line won't compile because Box<Number> is not related to Box<Integer>
	    // Box<Number> numBox = new Box<Integer>(31);
	    
	    // The following line is ok because numBox is not restricted to just Box<Number> 
	    Box<? extends Number> numBox = new Box<Integer>(31);
	    
	    
	  }
	  
	  
	  public void test_variance() {
	    Box<Integer> ib = new IntBox(23);
	    
	    
	    Box<?> b1 = new Box<Integer>(13);
	    Box<?> b2 = new Box<String>("Hello");  
	    
	  }
	  
	  public void test_holdsSuperClassOf() {
	    Box<Integer> intBox = new Box<Integer>(5);
	    Box<Number> numBox = new Box<Number>(3.5);
	    Box<String> strBox = new Box<String>("Hmmmm...");
	    SpecialBox<Integer> spBox = new SpecialBox<Integer>(42);
	    
	    // Integer is not a subclass of Double (held in the numBox)
	    assertFalse("intBox.holdsSuperClassOf(numBox)", intBox.holdsSuperClassOf(numBox));
	    
	    // Integer is a subclass of Integer
	    assertTrue("spBox.holdsSuperClassOf(intBox)", spBox.holdsSuperClassOf(intBox));
	        
	   // Integer is a subclass of Integer
	    assertTrue("intBox.holdsSuperClassOf(spBox)", intBox.holdsSuperClassOf(spBox));
	    
	    // String is not a subclass of Integer
	    assertFalse("strBox.holdsSuperClassOf(intBox)", strBox.holdsSuperClassOf(intBox));
	  }
	  
	  */

	}
	
	

}
